package exo4;

import java.util.ArrayList;
import java.util.List;

public final class Abonne {

	private static final String NL = "\n";
	private final String nom;
	private String adresse;
	private List<Ouvrage> reservations;
	private List<Ouvrage> emprunts;

	public Abonne(String nom, String adresse) {
		this.nom = nom;
		this.adresse = adresse;
		reservations = new ArrayList<Ouvrage>();
		emprunts = new ArrayList<Ouvrage>();
	}

	public String getNom() {
		return this.nom;
	}

	public String getAdresse() {
		return this.adresse;
	}

	public void setAdresse(String adresse) {
		this.adresse = adresse;
	}

	/*
	 * Pour un ouvrage donne, ne peut avoir qu'une reservation par type de
	 * media.
	 */
	public boolean addReservation(Ouvrage ouvrage) {
		boolean resultat = false;
		if (ouvrage != null && !aReserve(ouvrage)) {
			this.reservations.add(ouvrage);
			resultat = true;
		}
		return resultat;
	}

	public boolean aReserve(Ouvrage ouvrage) {
		return this.reservations.contains(ouvrage);
	}

	public boolean removeReservation(Ouvrage ouvrage) {
		return this.reservations.remove(ouvrage);
	}

	/*
	 * En lecture seulement : ne pas exposer la structure interne et se reserver
	 * la possibilité de changer son implantation quand on le souhaite. Recopie
	 * adaptée seulement aux collections de taille raisonnable, ce qui est le
	 * cas ici.
	 */
	public List<Ouvrage> getReservations() {
		return new ArrayList<Ouvrage>(this.reservations);
	}

	public boolean addEmprunt(Ouvrage ouvrage) {
		boolean resultat = false;
		if (ouvrage != null && !aEmprunte(ouvrage)) {
			this.emprunts.add(ouvrage);
			resultat = true;
		}
		return resultat;
	}

	public boolean aEmprunte(Ouvrage ouvrage) {
		return this.emprunts.contains(ouvrage);
	}

	public boolean removeEmprunt(Ouvrage ouvrage) {
		return this.emprunts.remove(ouvrage);
	}

	public List<Ouvrage> getEmprunts() {
		return new ArrayList<Ouvrage>(this.emprunts);
	}

	@Override
	public String toString() {
		StringBuffer abonneData = new StringBuffer();
		abonneData.append("\n======= Information sur l'abonné : ")
				.append(this.nom).append(" =======").append(NL)
				.append("Adresse : ").append(this.adresse).append(NL);
		if (!this.reservations.isEmpty()) {
			abonneData.append("Réservations en cours :").append(NL)
					.append(this.reservations.toString());
		} else {
			abonneData.append("Aucune réservation en cours.").append(NL);
		}
		if (!this.emprunts.isEmpty()) {
			abonneData.append("Emprunts en cours :").append(NL)
					.append(this.emprunts.toString());
		} else {
			abonneData.append("Aucune emprunt en cours.").append(NL);
		}
		return abonneData.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((adresse == null) ? 0 : adresse.hashCode());
		result = prime * result + ((nom == null) ? 0 : nom.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Abonne other = (Abonne) obj;
		if (adresse == null) {
			if (other.adresse != null)
				return false;
		} else if (!adresse.equals(other.adresse))
			return false;
		if (nom == null) {
			if (other.nom != null)
				return false;
		} else if (!nom.equals(other.nom))
			return false;
		return true;
	}
}
